using System;
using System.Windows.Input;

public class RelayCommand<T> : ICommand
{
      private readonly Func<T?, bool> _canExecute;
  private readonly Action<T?> _execute;

  public RelayCommand(Action<T?> execute, Func<T?, bool> canExecute = null!)
  {
      _canExecute=canExecute;
      _execute=execute??throw new ArgumentNullException(nameof(execute));
  }

  public event EventHandler? CanExecuteChanged
  {
      add { CommandManager.RequerySuggested+=value; }
      remove { CommandManager.RequerySuggested-=value; }
  }

  public bool CanExecute(object? parameter)
  {
      if (_canExecute==null)
          return true;
      if (parameter is T t) return _canExecute(t);
      return _canExecute(default);
  }

  public void Execute(object? parameter)
  {
      if (!CanExecute(parameter))
          return;
      if (parameter is T t)
          _execute(t);
      else
          _execute(default);
  }

  public void OnCanExecuteChanged()
  {
      CommandManager.InvalidateRequerySuggested();
  }
}